
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "emulator.h"

#include "screen.h"

//如果要使用LOGI,和LOGE请定义LOG_TAG这个宏
#define LOG_TAG "main"

//屏幕缓存地址，用于mythroad内部使用
mrp_screen *cache = NULL;
//屏幕真实地址，用于绘制文字等操作
mrp_screen *real_cache = NULL;

Bitmap java_cache = NULL, java_real_cache = NULL;

//手机屏幕真实宽高
int32 SCRW = 240, SCRH = 320;

//实际绘制图片画面宽高
int32 real_scrw = 240, real_scrh = 320;

//mrp系统屏幕宽高
int32 vm_scrw = 240, vm_scrh = 320;


#define memSize (1024 * 1024 * 2);

vm_info_t *vm = NULL;

char mr_printf_data[1000];
char*mr_printf_file = "/sdcard/mythroad/c/printf.txt";
void mr_printf(const char*format,...)
{
	
	va_list args;
	va_start(args,format);
	
	vsprintf(mr_printf_data,format,args);
	//strcat(mr_printf_data,"\n");

	if(1)
	{
		//写入文件
		int32 file = open(mr_printf_file,O_RDWR|O_CREAT,0777);
		if(file>=0){
			lseek(file,0,SEEK_END);
			write(file,mr_printf_data,strlen(mr_printf_data));
			close(file);
		}
	}
}

//行内存是连续的，所以可以一行一行的复制
void mr_drawBitmap(uint16*bmp,int16 x,int16 y,uint16 w,uint16 h)
{
	logi("mr_drawBitmap(%d,%d,%d,%d)",x,y,w,h);
	
	//可以理解为特效层，在缓存层上方
	if(x>=vm_scrw||y>=vm_scrh||w<=0||h<=0)
		return;

	if(1){
		uint16*p = mrp_getScrBuff(real_cache);
		for(int32 i = y;i<y+h;i++){
			memcpy((p+(vm_scrw*i)+x),(bmp+(vm_scrw*i)+x),w*2);
		}
	}
}

//删除文件
int32 mr_remove(const char*fullname){
	int32 result;
	logi("mr_remove(%s)",fullname);
	result = remove(fullname);
	if(result!=0){
		result MR_FAILED;
	}
	return result;
}

void on_bufferRefresh(vm_info_t *vm, uint16 *bmp, int16 x, int16 y, uint16 w, uint16 h)
{
	logi("-------->refreshBuffer");
	mr_drawBitmap(bmp,x,y,w,h);
}

int32 init_mrp()
{
	//创建虚拟机
	vm = vm_create(1024 * 400);
	//mem_init(vm);		 //初始化虚拟机内存
	//vm_install_func(vm); //安装函数

	sorftware_interrupt = on_sorftware_interrupt;
	
	vm_config_t conf;
	conf.screenWidth = vm_scrw;
	conf.screenHeight = vm_scrh;
	conf.networkId = 0;
	conf.sdcardDir = "/sdcard/";
	conf.dsmDir = "mythroad/";
	conf.IMEI = "IMEI";
	conf.IMSI = "IMSI";
	conf.manufactory = "YIZHI";
	conf.type = "MRPEMU";
	

	//设置一下虚拟机信息
	vm_setConfig(vm, &conf);

	vm_callback_t callbacks;
	callbacks.onBufferRefresh = on_bufferRefresh;
	vm->callbacks = callbacks;
	return 0;
}

void startMrp(char *path){
	logi("startMrp(%s)", path);
	
	if(cache!=NULL){
		mrp_freeScreen(cache);
		mrp_freeScreen(real_cache);
	}
	
	cache = mrp_createScreen(vm_scrw,vm_scrh);
	real_cache = mrp_createScreen(vm_scrw,vm_scrh);
	
	//启动mrp
	mr_start_dsm(vm, path);
}

//在程序启动时调用
void onCreate()
{
	mr_remove(mr_printf_file);
	init_mrp();
	logi("onCreate(scrw:%d, scrh:%d)", SCRW, SCRH);
}

//触摸事件调用
void onTouchEvent(int action,float x,float y,int index,int count,float pointersX[],float pointersY[],int pointersId[])
{
	int32 zz = real_scrw*vm_scrh/vm_scrw;
	int32 xx = (int)x*vm_scrw/real_scrw;
	int32 yy = (int)y*vm_scrh/zz;
	
	logi("onTouchEvent(%d,%d,%d)",action, xx, yy);
		
	if(action==2)
		action = 12;
	else if(action==0)
		action = 2;
	else if(action==1)
		action = 3;
	else
		return;
	
	if(xx<=vm_scrw&&yy<=vm_scrh){
		mr_event(vm, action, xx, yy);
	}
}

//只能在这里绘图
void onDraw(int left,int top,int right,int bottom,Canvas canvas)
{	
	Bitmap bmp;
	Paint paint = newPaint();
	
	bmp = mrp_screenBitmap(cache);
	Canvas_drawBitmap(canvas,bmp,0,0,vm_scrw,vm_scrh,0,0,real_scrw,real_scrh,paint);
	deleteBitmap(bmp);
	
	bmp = mrp_screenBitmap(real_cache);
	Canvas_drawBitmap(canvas,bmp,0,0,vm_scrw,vm_scrh,0,0,real_scrw,real_scrh,paint);
	deleteBitmap(bmp);
	
	deletePaint(paint);
	//mr_printf("onDraw");
}

//应用层屏幕变动
void vm_appSizeChange(int32 w, int32 h){
	
	int32 temp;
	SCRW = w;
	SCRH = h;
	
		//横竖屏切换
	if(SCRW<SCRH){
		real_scrw = SCRW;
		real_scrh = SCRW*vm_scrh/vm_scrw;
	}else{
		real_scrw = SCRH*vm_scrw/vm_scrh;
		real_scrh = SCRH;
	}
}

//屏幕大小发生变化时被调用 ，程序在启动后会调用一次
void onSizeChange(int w,int h,int oldw,int oldh,float density)
{
	logi("onSizeChange(scrw:%d, scrh:%d)", w, h);
	vm_appSizeChange(w, h);
}

//系统每1毫秒就会调用这个方法1次
void onLoopCall()
{
	postInvalidate();
	vm_timerCb(0);
}

//返回键被按下事件，如果 返回0则退出程序，
int onBackPressed()
{
	//vm_event(1, 18, 0);
	return -1;
}

//应用被暂停时调用，例如被后台运行
void onPause()
{
	//vm_pause();
}

//应用被恢复时调用，例如从后台运行转为前台运行
void onResume()
{
	//vm_resume();
}

//程序在被销毁时调用
void onDestroy()
{
	vm_free(vm);
	if(cache!=NULL){
		mrp_freeScreen(cache);
		mrp_freeScreen(real_cache);
	}
}
